import { _decorator, Component, find, Label, Node, tween, Tween, UITransform, Vec3, Widget } from 'cc';
import { DataProxy } from '../../../frame/A-LIB/sources/lib.b.data';
import { AudioManager } from '../../../frame/component/audio-manager';
import { ROUND_CONFIG } from '../../config/config.game';
import GameDC from '../../data/data.game.center';
const { ccclass, property } = _decorator;

@ccclass('Transition')
export class Transition extends Component {
	private uitrans: UITransform;
	private ui_background: UITransform;
	private ui_left: UITransform;
	private ui_right: UITransform;
	private ui_item_container: UITransform;
	private va_background: mtec.cc.VecAssist;
	private va_left: mtec.cc.VecAssist;
	private va_right: mtec.cc.VecAssist;
	private va_item_container: mtec.cc.VecAssist;
	private item_map: Map<number, {ui: UITransform, va: mtec.cc.VecAssist}>;

	private item_spaceX: number;
	private calculate_v3: Vec3;

	private ui_status: 'enter' | 'leave';

	protected onLoad(){
		this.init();
		this.listening();
	}

	protected start(){
		this.adaptUI();
		this.initUIStatus();
		this.node.active = false;
	}

	/** 初始化实例成员 */
	private init(){
		this.calculate_v3 = new Vec3();
		this.uitrans = this.node.getComponent(UITransform);
		this.ui_background = this.node.getChildByName('background').getComponent(UITransform);
		this.va_background = new mtec.cc.VecAssist(this.ui_background.node);

		[this.ui_left, this.ui_right, this.ui_item_container] = ['left', 'right', 'item']
		.map(word=>this.node.getChildByName('container-'+word).getComponent(UITransform));

		[this.va_left, this.va_right, this.va_item_container] = [this.ui_left, this.ui_right, this.ui_item_container]
		.map(ui=>new mtec.cc.VecAssist(ui.node));

		this.item_map = new Map();
		[1, 2, 3, 4].forEach(idx=>{
			let ui = this.ui_item_container.node.getChildByName('round-'+idx).getComponent(UITransform);
			let va = new mtec.cc.VecAssist(ui.node);
			this.item_map.set(idx, {ui, va});
		});
	}

	/** 适配UI内容 */
	private adaptUI(){
		// 通过widget组件撑开容器
		let wgt = this.node.getComponent(Widget);
		if(!wgt){
			wgt = this.node.addComponent(Widget);
			[wgt.isAlignTop, wgt.isAlignBottom, wgt.isAlignLeft, wgt.isAlignRight] = [true, true, true, true];
			[wgt.isAbsoluteTop, wgt.isAbsoluteBottom, wgt.isAbsoluteLeft, wgt.isAbsoluteRight] = [true, true, true, true];
			[wgt.top, wgt.bottom, wgt.left, wgt.right] = [0, 0, 0, 0];
		}
		wgt.updateAlignment();

		// 适配背景，等比缩放
		mtec.cc.adaptBackgroundNode(this.ui_background.node);
	}

	/** 初始化UI状态 */
	private initUIStatus(){
		// 设置两侧信息板初始位置
		this.va_left.vec.set(this.ui_left.node.position);
		this.va_right.vec.set(this.ui_right.node.position);
		this.va_left.vec.x = this.va_left.over_left;
		this.va_right.vec.x = this.va_right.over_right;
		this.ui_left.node.setPosition(this.va_left.vec);
		this.ui_right.node.setPosition(this.va_right.vec);

		// 设置item容器初始UI状态
		let one_of_the_item = this.item_map.get(1);
		this.ui_item_container.width = this.uitrans.width;
		this.item_spaceX = (this.uitrans.width - (one_of_the_item.ui.width * this.item_map.size)) / (this.item_map.size + 1);
		this.item_map.forEach(({ui, va}, idx)=>{
			va.vec.set(ui.node.position);
			va.vec.y = va.bottom;
			va.vec.x = va.left + idx * this.item_spaceX + (idx-1) * ui.width;
			ui.node.setPosition(va.vec);
		});
		this.va_item_container.vec.set(this.ui_item_container.node.position);
		this.va_item_container.getPosition('over_right', 'top');
		this.ui_item_container.node.setPosition(this.va_item_container.vec);

		this.ui_left.node.getChildByName('lbl-ROUND').getComponent(Label).string = 'Level ';
		this.ui_right.node.getChildByName('lbl-MULTIPLE').getComponent(Label).string = 'Reward Increase';

		this.item_map.forEach((el, idx)=>{
			el.ui.node.getChildByName('lbl-ROUND').getComponent(Label).string = 'LEVEL';
			el.ui.node.getChildByName('lbl-round').getComponent(Label).string = idx.toString();
		})
	}

	private listening(){
		DataProxy.follow(GameDC.Trigger, 'UITrans', (o, v)=>this.onUITransTrigger(v, o), false);
	}

	private onUITransTrigger(show: boolean, ov: boolean){
		if(show){
			this.enter();
		}else{
			this.leave();
		}
	}

	private enter(){
		if(this.ui_status==='enter'){
			return void 0;
		}
		this.ui_status = 'enter';

		AudioManager.playEffect(AudioManager.EAudio.EF_TRANSITION);
		this.node.active = true;

		this.ui_left.node.getChildByName('lbl-round').getComponent(Label).string = GameDC.Cache.round_curr.toString();
		this.ui_right.node.getChildByName('lbl-multiple').getComponent(Label).string = 'Up to XX times'.replace('XX', ROUND_CONFIG.find(el=>el.round===GameDC.Cache.round_curr).multiple.toString());

		[this.ui_left, this.ui_right].forEach(ui=>Tween.stopAllByTarget(ui.node));
		this.va_left.vec.x = this.va_left.left
		this.va_right.vec.x = this.va_right.right;

		let duration = 0.5;
		tween(this.ui_left.node).to(duration, {position: this.va_left.vec}, {easing: 'cubicOut'}).start();
		tween(this.ui_right.node).to(duration, {position: this.va_right.vec}, {easing: 'cubicOut'}).start();

		let {round_curr, round_last} = GameDC.Cache;

		// 设置初始状态
		let speed_item = this.item_map.get(1).ui.height / duration;
		let item_width = this.item_map.get(1).ui.width;

		Tween.stopAllByTarget(this.ui_item_container.node);
		this.va_item_container.getPosition('over_right', 'top');
		this.va_item_container.vec.x = this.va_item_container.over_right - Math.min(round_last+1, 4) * (item_width + this.item_spaceX);
		this.ui_item_container.node.setPosition(this.va_item_container.vec);

		this.item_map.forEach(({ui, va}, idx)=>{
			ui.node.active = (idx-1)<=round_last;
			if(!ui.node.active){
				return void 0;
			}

			Tween.stopAllByTarget(ui.node);
			ui.node.setPosition(ui.node.position.x, va.over_top, va.vec.z);
			this.refreshRoundItemUI(ui.node, idx<round_last ? 'pass' : idx==round_last ? 'curr' : 'lock');

			va.vec.y = va.top;
			if(idx==round_last){
				va.vec.add3f(0, -156.5, 0);
			}

			let time = Vec3.subtract(this.calculate_v3, va.vec, ui.node.position).length() / speed_item;
			duration = Math.max(duration, time);

			tween(ui.node).to(time, {position: va.vec}, {easing: 'bounceOut'}).start();
		});

		// 设置下一状态
		if(round_curr==round_last){
			mtec.delay(duration + 2, ()=>{
				GameDC.Trigger.UITrans = false;
			});
			return void 0;
		}

		this.va_item_container.vec.x = this.va_item_container.over_right - Math.min(round_curr+1, 4) * (item_width + this.item_spaceX);

		tween(this.ui_item_container.node).delay(duration+0.2)
		.to(duration, {position: this.va_item_container.vec}).start();

		mtec.delay(duration+0.2, ()=>{
			this.item_map.forEach(({ui, va}, idx)=>{
				ui.node.active = (idx-1)<=round_curr;
				if(!ui.node.active){
					return void 0;
				}

				Tween.stopAllByTarget(ui.node);
				va.vec.y = va.top;
				if(idx==round_curr){
					va.vec.add3f(0, -156.5, 0);
				}

				let tw = tween(ui.node).to(duration, {position: va.vec}, {easing: 'bounceOut'});

				if(idx==round_curr){
					this.refreshRoundItemUI(ui.node, 'curr');
				}else{
					tw = tw.call(()=>this.refreshRoundItemUI(ui.node, idx<round_curr ? 'pass' : 'lock'));
				}
				tw.start();
			});

			mtec.delay(duration + 2, ()=>GameDC.Trigger.UITrans = false);
		});
	}

	private leave(){
		if(this.ui_status==='leave'){
			return void 0;
		}
		this.ui_status = 'leave';

		let duration = 0.5;
		let speed_item = this.item_map.get(1).ui.height / duration;

		let {round_curr, round_last} = GameDC.Cache;

		this.item_map.forEach(({ui, va}, idx)=>{
			if(!ui.node.active){
				return void 0;
			}

			va.vec.y = va.over_top;
			let time = Vec3.subtract(this.calculate_v3, va.vec, ui.node.position).length() / speed_item;
			duration = Math.max(duration, time);

			Tween.stopAllByTarget(ui.node);

			let tw = tween(ui.node);

			if(idx==round_curr){
				tw = tw.delay(time * 0.5);
			}

			tw.to(time, {position: va.vec}, {easing: 'cubicOut'}).start();
		});

		[this.ui_left, this.ui_right].forEach(ui=>Tween.stopAllByTarget(ui.node));
		this.va_left.vec.x = this.va_left.over_left;
		this.va_right.vec.x = this.va_right.over_right;

		tween(this.ui_right.node).to(duration, {position: this.va_right.vec}, {easing: 'cubicOut'}).start();
		tween(this.ui_left.node)
		.to(duration, {position: this.va_left.vec}, {easing: 'cubicOut'})
		.call(()=>{
			this.node.active = false;
			GameDC.Trigger.UIHome = true;
			GameDC.Trigger.UIGame = true;
		})
		.start();
	}

	private refreshRoundItemUI(item: Node, type: 'pass' | 'curr' | 'lock'){
		let curr = type == 'curr';

		item.getChildByName('background').children.forEach(n=>n.active = n.name==type);
		find('rope/long', item).active = curr;
		find('rope/short', item).active = !curr;
	}
}

